package com.ddwl.order.mq;

import com.alibaba.fastjson.JSON;
import com.ddwl.common.config.DingTalkNotify;
import com.ddwl.common.constant.BaseEnum;
import com.ddwl.common.constant.OrderEnum;
import com.ddwl.common.constant.RabbitMqConstants;
import com.ddwl.order.service.*;
import com.ddwl.schema.bo.order.CreateSeckillOrderBo;
import com.ddwl.schema.bo.order.ThirdPartRecordBo;
import com.ddwl.schema.vo.funds.OrderPaymentVo;
import com.ddwl.schema.vo.funds.OrderRefundsVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;


/**
 * 类RabbitMqListener.java的实现描述：TODO
 *
 * @author zach
 * @Date :2019-05-08 14:55.
 */
@Component
@Slf4j
public class RabbitMqMessageReceiver {


    @Resource
    private OrderInfoServer orderInfoServer;
    @Resource
    private OrderPayServer orderPayServer;
    @Resource
    private AfterSaleOrderServer afterSaleOrderServer;
    @Resource
    private SeckillService seckillService;
    @Resource
    private DingTalkNotify dingTalkNotify;
    @Resource
    private ShopAfterSaleOrderServer shopAfterSaleOrderServer;

    /**
     * 接收订单超时关闭消息
     *
     * @param orderNo
     */
    @RabbitListener(queues = RabbitMqConstants.ORDER_TIMEOUT_REDIRECT_QUEUE)
    public void receive(String orderNo) {
        log.info("订单过期开始关闭订单消息 orderNo={}", orderNo);
        try {
            orderInfoServer.orderAutoClosed(orderNo);
        } catch (Exception e) {
            log.error("订单过期关闭异常 order = {}", orderNo, e);
            dingTalkNotify.exceptionNotify(e);
        }
    }

    /**
     * 记录第三方调用信息消息
     *
     * @param thirdPartRecordBo
     */
    @RabbitListener(bindings = {@QueueBinding(value = @Queue(value = RabbitMqConstants.THIRD_PART_RECORD_QUEUE, durable = "true"),
            exchange = @Exchange(value = RabbitMqConstants.DIST_EXCHANGE), key = RabbitMqConstants.THIRD_PART_RECORD_QUEUE)})
    public void thirdPartRecord(String thirdPartRecordBo) {
        ThirdPartRecordBo partRecordBo = JSON.parseObject(thirdPartRecordBo, ThirdPartRecordBo.class);
        log.info("开始记录第三方调用消息 appId={}", partRecordBo.getAppId());
        try {
            orderInfoServer.thirdPartRecord(partRecordBo);
        } catch (Exception e) {
            log.error("记录第三方调用消息异常 appId={}", partRecordBo.getAppId(), e);
            dingTalkNotify.exceptionNotify(e);
        }
    }

    /**
     * 处理订单支付完成消息
     *
     * @param OrderPayVoJson
     */
    @RabbitListener(bindings = {@QueueBinding(value = @Queue(value = RabbitMqConstants.ORDER_PAY_NOTIFY_QUEUE, durable = "true"),
            exchange = @Exchange(value = RabbitMqConstants.ORDER_EXCHANGE), key = RabbitMqConstants.ORDER_PAY_NOTIFY_QUEUE)})
    public void orderPayNotify(String OrderPayVoJson) {
        OrderPaymentVo partRecordBo = JSON.parseObject(OrderPayVoJson, OrderPaymentVo.class);
        log.info("开始处理订单支付完成消息 partRecordBo={}", JSON.toJSONString(partRecordBo));
        try {
            orderPayServer.completePaymentNew(partRecordBo);
        } catch (Exception e) {
            log.error("记录第三方调用消息异常 partRecordBo={}", JSON.toJSONString(partRecordBo), e);
            dingTalkNotify.exceptionNotify(e);
        }
    }

    /**
     * 处理售后信息消息
     *
     * @param orderRefunds
     */
    @RabbitListener(bindings = {@QueueBinding(value = @Queue(value = RabbitMqConstants.AFTER_SALE_REFUND_QUEUE, durable = "true"),
            exchange = @Exchange(value = RabbitMqConstants.ORDER_EXCHANGE), key = RabbitMqConstants.AFTER_SALE_REFUND_QUEUE)})
    public void afterSaleRefundNotify(String orderRefunds) {
        OrderRefundsVo orderRefundsVo = JSON.parseObject(orderRefunds, OrderRefundsVo.class);
        log.info("开始处理退款完成消息 orderRefundsVo={}", JSON.toJSONString(orderRefundsVo));
        try {
            afterSaleOrderServer.completeRefund(orderRefundsVo);
        } catch (Exception e) {
            log.error("记录退款消息异常 orderRefundsVo={}", JSON.toJSONString(orderRefundsVo), e);
            dingTalkNotify.exceptionNotify(e);
        }
    }

    /**
     * 处理店铺售后信息消息
     *
     * @param orderRefunds
     */
    @RabbitListener(bindings = {@QueueBinding(value = @Queue(value = RabbitMqConstants.SHOP_AFTER_SALE_REFUND_QUEUE, durable = "true"),
            exchange = @Exchange(value = RabbitMqConstants.ORDER_EXCHANGE), key = RabbitMqConstants.SHOP_AFTER_SALE_REFUND_QUEUE)})
    public void shopAfterSaleRefundNotify(String orderRefunds) {
        OrderRefundsVo orderRefundsVo = JSON.parseObject(orderRefunds, OrderRefundsVo.class);
        log.info("开始处理店铺退款完成消息 orderRefundsVo={}", JSON.toJSONString(orderRefundsVo));
        try {
            shopAfterSaleOrderServer.completeRefund(orderRefundsVo);
        } catch (Exception e) {
            log.error("记录店铺退款消息异常 orderRefundsVo={}", JSON.toJSONString(orderRefundsVo), e);
            dingTalkNotify.exceptionNotify(e);
        }
    }

    /**
     * 秒杀快速下单消息
     *
     * @param createSeckillOrderString
     */
    @RabbitListener(bindings = {@QueueBinding(value = @Queue(value = RabbitMqConstants.FAST_SECKILL_ORDER_QUEUE, durable = "true"),
            exchange = @Exchange(value = RabbitMqConstants.ORDER_EXCHANGE), key = RabbitMqConstants.FAST_SECKILL_ORDER_QUEUE)})
    public void createSeckillOrderNotify(String createSeckillOrderString) {
        CreateSeckillOrderBo createSeckillOrderBo = JSON.parseObject(createSeckillOrderString, CreateSeckillOrderBo.class);
        log.info("开始处理秒杀快速下单消息 createSeckillOrderBo={}", JSON.toJSONString(createSeckillOrderBo));
        try {
            String orderId = seckillService.fastCreateOrder(createSeckillOrderBo);
            seckillService.secondKillOrderNotify(createSeckillOrderBo.getMasterOrderId(), orderId, OrderEnum.PayStatus.SUCCEED.getCode());
        } catch (Exception e) {
            log.error("秒杀快速下单消息异常 createSeckillOrderBo={}", JSON.toJSONString(createSeckillOrderBo), e);
            seckillService.secondKillOrderNotify(createSeckillOrderBo.getMasterOrderId(), null, OrderEnum.PayStatus.FILL.getCode());
            dingTalkNotify.exceptionNotify(e);
        }
    }
}
